package com.chris.code.service;

import com.chris.code.model.Database;
import com.chris.code.model.Field;
import com.chris.code.model.Table;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * Copyright (c) 2018-2025, chris All rights reserved.
 * <p>
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * <p>
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * <p>
 * Author: haoka (haokang207@126.com)
 * <p>
 * Date: 2018/9/30 9:35
 * 读取数据库metadata
 **/
@Service
public class DatabaseService {
    public List<Table> fetchTables(Database database) throws SQLException, ClassNotFoundException {
        DatabaseMetaData metaData = getConnection(database).getMetaData();
        ResultSet tables = metaData.getTables(null, "%", "%", new String[]{"TABLE"});
        List<Table> list = new ArrayList<>();
        while (tables.next()) {
            Table table = new Table();
            table.setName(tables.getString("TABLE_NAME"));
            table.setType(tables.getString("TABLE_TYPE"));
            table.setRemark(tables.getString("REMARKS"));
            ResultSet primaryKeyResultSet = metaData.getPrimaryKeys(null, null, table.getName());
            while (primaryKeyResultSet.next()) {
                table.setPrimary(primaryKeyResultSet.getString("COLUMN_NAME"));
                break;
            }
            list.add(table);
        }
        return list;
    }

    public List<Field> fetchTableField(Database database, String tableName) throws SQLException, ClassNotFoundException {
        DatabaseMetaData metaData = getConnection(database).getMetaData();
        ResultSet fields = metaData.getColumns(null, "%", tableName, "%");
        List<Field> list = new ArrayList<>();
        while (fields.next()) {
            Field field = new Field();
            field.setName(fields.getString("COLUMN_NAME"));
            field.setType(fields.getInt("DATA_TYPE"));
            field.setTypeName(fields.getString("TYPE_NAME"));
            field.setSize(fields.getInt("COLUMN_SIZE"));
            field.setNullable(fields.getBoolean("NULLABLE"));
            field.setRemark(fields.getString("REMARKS"));
            field.setDefaultValue(fields.getString("COLUMN_DEF"));
            field.setRefTable(fields.getString("SCOPE_TABLE"));
            field.setRefField(fields.getString("SOURCE_DATA_TYPE"));
            field.setRefType(fields.getShort("SOURCE_DATA_TYPE"));
            field.setAutoIncrement(fields.getString("IS_AUTOINCREMENT"));
            list.add(field);
        }
        return list;
    }

    private Connection getConnection(Database database) throws SQLException, ClassNotFoundException {
        Properties props = new Properties();
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://" + database.getHost() + ":" + database.getPort() + "/" + database.getSchema()
                + "?characterEncoding=UTF-8";
        props.setProperty("user", database.getUsername());
        props.setProperty("password", database.getPassword());
        props.setProperty("remarks", "true");
        props.setProperty("useInformationSchema", "true");
        return DriverManager.getConnection(url, props);
    }
}
